package com.cqndt.disaster.device.common.influxdb;

import org.influxdb.InfluxDB;
import org.influxdb.InfluxDBFactory;
import org.influxdb.dto.Point;
import org.influxdb.dto.Query;
import org.influxdb.dto.QueryResult;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author Frog
 */
public class InfluxDBConnect {
    /**
     * 用户名
     */
    private String username;
    /**
     * 密码
     */
    private String password;
    /**
     * 连接地址
     */
    private String openurl;
    /**
     * 数据库
     */
    private String database;

    private InfluxDB influxDB;

    public InfluxDBConnect(String username, String password, String openurl, String database) {
        this.username = username;
        this.password = password;
        this.openurl = openurl;
        this.database = database;
    }
    /**
     * 关闭数据库
     */
    public void close() {
        influxDB.close();
    }

    /**
     * 连接时序数据库；获得InfluxDB
     **/
    public InfluxDB influxDbBuild() {
        if (influxDB == null) {
            influxDB = InfluxDBFactory.connect(openurl, username, password);
            influxDB.createDatabase(database);

        }
        return influxDB;
    }

    /**
     * 设置数据保存策略 defalut 策略名 /database 数据库名/ 30d 数据保存时限30天/ 1 副本个数为1/ 结尾DEFAULT
     * 表示 设为默认的策略
     */
    public void createRetentionPolicy() {
        String command = String.format("CREATE RETENTION POLICY \"%s\" ON \"%s\" DURATION %s REPLICATION %s DEFAULT",
                "defalut", database, "30d", 1);
        this.query(command);
    }

    /**
     * 查询
     *
     * @param command 查询语句
     * @return
     */
    public QueryResult query(String command) {
        return influxDB.query(new Query(command, database));
    }

    /**
     * 插入
     *
     * @param measurement 表
     * @param tags        标签
     * @param fields      字段
     */
    public void insert(String measurement, Map<String, String> tags, Map<String, Object> fields) {
        Point.Builder builder = Point.measurement(measurement);
        builder.time(((long) fields.get("currentTime") + 28800) * 1000000000, TimeUnit.NANOSECONDS);
        fields.remove("currentTime");
        builder.tag(tags);
        builder.fields(fields);
        //
        influxDB.write(database, "", builder.build());
    }

    /**
     * 删除
     *
     * @param command 删除语句
     * @return 返回错误信息
     */
    public String deleteMeasurementData(String command) {
        QueryResult result = influxDB.query(new Query(command, database));
        return result.getError();
    }

    /**
     * 创建数据库
     *
     * @param dbName
     */
    public void createDB(String dbName) {
        influxDB.createDatabase(dbName);
    }

    /**
     * 删除数据库
     *
     * @param dbName
     */
    public void deleteDB(String dbName) {
        influxDB.deleteDatabase(dbName);
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getOpenurl() {
        return openurl;
    }

    public void setOpenurl(String openurl) {
        this.openurl = openurl;
    }

    public void setDatabase(String database) {
        this.database = database;
    }

    public int countSensorData(String sensorNo, String measurement) {
        String command = "select count(value) from " + measurement + " where sensor_no = " + "'" + sensorNo + "'";
        QueryResult query = influxDB.query(new Query(command, database));
        List<Map<String, Object>> mapList = queryResultToListMap(query);
        if (mapList.size() > 0) {
            Integer count = Double.valueOf(mapList.get(0).get("count").toString()).intValue();
            return count;
        }
        return 0;
    }

    /**
     * 将influxdb查询的结果解析成List<Map>
     *
     * @param query
     * @return mapList
     */
    public List<Map<String, Object>> queryResultToListMap(QueryResult query) {
        List<Map<String, Object>> mapList = new ArrayList<>(16);
        List<QueryResult.Result> results = query.getResults();
        for (QueryResult.Result result : results) {
            List<QueryResult.Series> seriesList = result.getSeries();
            if (null != seriesList) {
                for (QueryResult.Series series : seriesList) {
                    List<List<Object>> values = series.getValues();
                    for (List<Object> value : values) {
                        Map<String, Object> map = new HashMap<>(16);
                        List<String> columns = series.getColumns();
                        for (int i = 0; i < columns.size(); i++) {
                            map.put(columns.get(i), value.get(i));
                        }
                        mapList.add(map);
                    }
                }
            }
        }
        return mapList;
    }

    public String selectLastRecordTime(String sensorNo, String measurementXQX) {
        String command = "select * from " + measurementXQX + " where sensor_no='" + sensorNo + "' order by time desc limit 1";
        QueryResult query = query(command);
        List<Map<String, Object>> mapList = queryResultToListMap(query);
        if(mapList.size() == 0){
            return null;
        }
        String replace = mapList.get(0).get("time").toString().replace("T", " ");
        String sTime = replace.replace("Z", "");
        return sTime;
    }
}
